arm64架构linux内核地址转换 |
您所在的位置:网站首页 › arm64 地址空间 › arm64架构linux内核地址转换 |
本文基于:linux-5.11
在基于arm64架构的linux内核中, 有两个 表示__pa(x)和__va(x)用于物理地址转换位虚拟地址 或者 虚拟地址转换为物理地址(实际上还有一个__pa_symbol(x))。 这两个表达式是如何进行虚/实地址转换的?这种转换关系是如何确立的?为什么这样转换? 本文就这些问题进行挖掘探究。 一、层层展开,还原__pa(x)全貌表达式__pa(x)是一个宏,定义在arch/arm64/include/asm/memory.h文件中: #define __pa(x) __virt_to_phys((unsigned long)(x))上面的__virt_to_phys()在调试配置没有开 CONFIG_DEBUG_VIRTUAL=n 时也由宏定义在arch/arm64/include/asm/memory.h: #define __virt_to_phys(x) __virt_to_phys_nodebug(x)上面的 __virt_to_phys_nodebug 是一个宏,还是定义在同一个文件中: #define __virt_to_phys_nodebug(x) ({ \ phys_addr_t __x = (phys_addr_t)(__tag_reset(x)); \ __is_lm_address(__x) ? __lm_to_phys(__x) : __kimg_to_phys(__x); \ })这个就是arm64架构linux内核中__pa(x)的全貌。 其中,__tag_reset(x)是去掉虚拟地址中的tag(如果有tag的话),让虚拟地址还原为真正可用的虚拟地址,我们这里可以直接理解为没有tag的普通虚拟地址。 接着,第二条指令"__is_lm_address(__x) ? __lm_to_phys(__x) : __kimg_to_phys(__x)",判断虚拟地址__x是否是在线性区域,如果是则用__lm_to_phys(__x)将虚拟地址转换为物理地址;否则用__kimg_to_phys(__x)将虚拟地址转换为物理地址。 这里出现了三个表达式:__is_lm_address(),__lm_to_phys()以及__kimg_to_phys(),它们都是什么含义呢?接下来一一分析。 1.1 判断虚拟地址是否为线性地址宏__is_lm_address(addr)用于判断虚拟地址addr是否在arm64的虚拟地址空间的线性地址区域,其实现如下: /* * Check whether an arbitrary address is within the linear map, which * lives in the [PAGE_OFFSET, PAGE_END) interval at the bottom of the * kernel's TTBR1 address range. */ #define __is_lm_address(addr) (((u64)(addr) - PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET))这个宏判断虚拟地址addr是否处于[PAGE_OFFSET, PAGE_END)范围,如果是则说明addr是线性区域的虚拟地址。 在arm64架构中对于虚拟地址空间为48-bit (CONFIG_ARM64_VA_BITS=48是典型的有效虚拟地址配置,还有39-bit和52-bit可选) 的情况, PAGE_OFFSET = (-(UL(1) |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |